import pygame
import math


class AStar:
   def __init__(self, width, height, block_size=80):
       self.width = width   # 棋盘宽度（六边形个数）
       self.height = height   # 棋盘高度（六边形个数）
       self.block_size = block_size  # 每个六边形的尺寸
       self.surface = pygame.Surface((self.block_size * self.width, self.block_size * self.height))
       self.surface.fill((224, 224, 224))
       self.font = pygame.font.SysFont("Arial", int(self.block_size * 0.4))
       self.board_offset_x = self.block_size * 0.3
       self.board_offset_y = self.block_size * 0.4
       self.board_cols = 4
       self.board_rows = 3
       self.button_offset_x = 40
       self.button_offset_y = 20
       self.button_width = 120
       self.button_height = 50
       self.piece_radius = int(self.block_size * 0.4)
       self.yellow = (255, 235, 59)  # 黄色棋子
       self.red = (255, 87, 34)  # 红色棋子
       self.brown = (121, 85, 72)  # 棕色棋子
       self.board = [[0] * self.width for _ in range(self.height)]

   def _get_block_position(self, x, y):
       """获取六边形中心点坐标"""
       offset_x = self.board_offset_x if y % 2 == 1 else 0
       center_x = int(self.block_size * 1.5 * x + self.block_size + offset_x)
       center_y = int(self.block_size * math.sqrt(3) * (y + 0.5))
       return center_x, center_y

   def _get_block_by_pixel(self, x, y):
       """根据像素坐标获取所在的六边形"""
       col = int((x - self.board_offset_x) / (self.block_size * 1.5))
       row = int(y / (self.block_size * math.sqrt(3)))
       if col < 0 or col >= self.width or row < 0 or row >= self.height:
           return None
       offset_x = self.board_offset_x if row % 2 == 1 else 0
       center_x, center_y = self._get_block_position(col, row)
       dx = x - center_x
       dy = y - center_y
       if abs(dx) <= self.block_size * 0.5:
           return col, row
       elif dx < 0:
           if dy < 0:
               return col - 1, row - 1 if row % 2 == 1 else row
           else:
               return col - 1, row if row % 2 == 1 else row + 1
       else:
           if dy < 0:
               return col + 1, row - 1 if row % 2 == 1 else row
           else:
               return col + 1, row if row % 2 == 1 else row + 1

   def _get_next_moves(self, x, y):
       """获取指定位置的可行移动方向"""
       moves = []
       if x - 2 >= 0:
           if y - 1 >= 0 and self.board[y - 1][x - 1] == 0 and self.board[y - 1][x - 2] == 0:
               moves.append((x - 2, y - 1))
           if y + 1 < self.height and self.board[y + 1][x - 1] == 0 and self.board[y + 1][x - 2] == 0:
               moves.append((x - 2, y + 1))
       if x - 1 >= 0 and y - 2 >= 0 and self.board[y - 2][x - 1] == 0 and self.board[y - 1][x - 1] == 0:
           moves.append((x - 1, y - 2))
       if x + 1 < self.width and y - 2 >= 0 and self.board[y - 2][x + 1] == 0 and self.board[y - 1][x] == 0:
           moves.append((x + 1, y - 2))
       if x + 2def draw_board(self):
       """绘制棋盘和棋子"""
       for j in range(self.height):
           for i in range(self.width):
               center_x, center_y = self._get_block_position(i, j)
               color = (255, 255, 255)
               if (i + j) % 2 == 0:
                   pygame.draw.polygon(self.surface, color, [(center_x - self.block_size // 2, center_y), (center_x - self.block_size // 4, center_y - self.block_size // 2), (center_x + self.block_size // 4, center_y - self.block_size // 2), (center_x + self.block_size // 2, center_y), (center_x + self.block_size // 4, center_y + self.block_size // 2), (center_x - self.block_size // 4, center_y + self.block_size // 2)])
               else:
                   pygame.draw.rect(self.surface, color, (center_x - self.block_size // 2, center_y - self.block_size // 2, self.block_size, self.block_size))
       for j in range(self.height):
           for i in range(self.width):
               if self.board[j][i] != 0:
                   color = self.yellow if self.board[j][i] == 1 else self.red if self.board[j][i] == 2 else self.brown
                   pygame.draw.circle(self.surface, color, self._get_block_position(i, j), self.piece_radius)
       # 计算五角星各个点坐标
       R = int(self.block_size / 3)  # 五角星所在圆的半径
       center_x, center_y = self._get_block_position(2, 2)  # 五角星所在六边形的中心坐标
       offset = 0.5 * R / math.sin(math.pi / 5)  # 角平分线长度
       points = [(center_x + offset * math.cos(2 * math.pi * i / 5), center_y + offset * math.sin(2 * math.pi * i / 5)) for i in range(5)]
       cross_points = [(center_x + R * math.cos(2 * math.pi * (0.5 + i) / 5 - math.pi / 2), center_y + R * math.sin(2 * math.pi * (0.5 + i) / 5 - math.pi / 2)) for i in range(5)]
       # 绘制五角星
       pygame.draw.lines(self.surface, (0, 0, 0), True, points + cross_points, 2)

   def draw_piece(self, color, x, y):
       """绘制棋子"""
       pygame.draw.circle(self.surface, color, self._get_block_position(x, y), self.piece_radius)
       text_surface = self.font.render(str(x + y * self.width), True, (0, 0, 0))
       text_rect = text_surface.get_rect(center=self._get_block_position(x, y))
       self.surface.blit(text_surface, text_rect)

   def draw_button(self, text, x, y, function):
       """绘制按钮"""
       rect = pygame.Rect(x, y, self.button_width, self.button_height)
       pygame.draw.rect(self.surface, (3, 169, 244), rect)
       text_surface = self.font.render(text, True, (255, 255, 255))
       text_rect = text_surface.get_rect(center=rect.center)
       self.surface.blit(text_surface, text_rect)
       mouse_pos = pygame.mouse.get_pos()
       if rect.collidepoint(mouse_pos):
           pygame.draw.rect(self.surface, (255, 255, 255), rect, 3)
           if pygame.mouse.get_pressed()[0] == 1:
               function()

   def on_mouse_down(self, x, y):
       """鼠标左键按下事件"""
       block = self._get_block_by_pixel(x, y)
       if block is None:
           return
       piece = self.board[block[1]][block[0]]
       if piece == 0:
           return
       self.selected_piece = (block[0], block[1])
       self.valid_moves = self._get_next_moves(block[0], block[1])
       self.draw_valid_moves()

   def on_mouse_up(self, x, y):
       """鼠标左键松开事件"""
       if self.selected_piece is not None:
           src_x, src_y = self.selected_piece
           dest_block = self._get_block_by_pixel(x, y)
           if dest_block == self.selected_piece:
               pass
           elif dest_block is None:
               self.board[src_y][
